package three_star_craft.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;

import org.grlea.log.SimpleLogger;

import three_star_craft.ClientMain;
import three_star_craft.uap.UapConnectionListener;
import three_star_craft.uap.UapGenerator;
import ProtocolsCommon.Common.PlayableItem;
import UserApplicationPart.UAP;

/**
 * @author w.antosiewic
 *
 */
public class GuiMain extends JFrame implements UapConnectionListener
{
	private static final long serialVersionUID = 3270723582995274115L;

	private static final SimpleLogger logger = new SimpleLogger(GuiMain.class);
	
	private static final String titlePrefix = "Three Star Craft - UserClient";
	
	private ClientMain _clientMain;
	private JToolBar _toolBar;
	private JButton _connectButton;
	private JButton _disconnectButton;
	
	private JTable _mediaTable;
	private JScrollPane _mediaScrollPane;
	
	// dialog displayed during establishment of UAP connection
	private ConnectingDialog _connectingDialog;
	
	/**
	 * @throws HeadlessException
	 */
	public GuiMain() throws HeadlessException {
		super(titlePrefix);

		buildGui();
		
		// take care of closing the application
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0){
                
                _clientMain.releaseAll();
                
                System.exit(0);
            }
        });
        
        setVisible(true);
	}

	private void buildGui()
	{
	    this.setLayout(new GridBagLayout());
	    _toolBar = new JToolBar();
	    this.add(_toolBar, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.5, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
	    
	    _connectButton = new JButton("Connect");
	    _connectButton.addActionListener(new ConnectButtonAction());
	    _toolBar.add(_connectButton);
	    
	    _disconnectButton = new JButton("Disconnect");
        _disconnectButton.addActionListener(new DisconnectButtonAction());
        _disconnectButton.setEnabled(false);
        _toolBar.add(_disconnectButton);
	
	    _mediaTable = new JTable(new MediaTableModel());
	    _mediaTable.setBorder(new EtchedBorder());
	    _mediaScrollPane = new JScrollPane(_mediaTable);
	    _mediaTable.setFillsViewportHeight(true);
	    _mediaTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	    _mediaTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e){
                if(e.getClickCount() == 2)
                {
                    int row = _mediaTable.getSelectedRow();
                    logger.debugObject("Selected item in row:", row);
                    PlayableItem i = ((MediaTableModel)_mediaTable.getModel()).getItem(row);
                    if(_clientMain.establishBearer(i.getId()))
                    {
                        _connectingDialog.setVisible(true);
                    }
                }
            }
        });
	    this.add(_mediaScrollPane, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0));
	    
	    setSize(Toolkit.getDefaultToolkit().getScreenSize().width/2, Toolkit.getDefaultToolkit().getScreenSize().height - 200);
        setLocationRelativeTo(null); // center window on screen
        
	}
	
	public void setClientMain(ClientMain clientMain)
	{
	    _clientMain = clientMain;
	}
	
	private class ConnectButtonAction implements ActionListener
	{
        public void actionPerformed(ActionEvent arg0)
        {
            _connectingDialog = new ConnectingDialog(GuiMain.this);
            _connectingDialog.setVisible(true);
            
            if(!_clientMain.establishConnection())
            {
                logger.warn("Failed to send UAPConnectionReq");
                _connectingDialog.setVisible(false);
                
                JOptionPane.showMessageDialog(
                    GuiMain.this,
                    "Cannot connect with Three Star Craft server",
                    "Connection failure",
                    JOptionPane.WARNING_MESSAGE,
                    null);
            }
            else 
            {
                logger.debug("UAPConnectionReq sent");
                _connectButton.setEnabled(false);
            }
        }
	}

	private class DisconnectButtonAction implements ActionListener
    {
        public void actionPerformed(ActionEvent arg0)
        {
            logger.debug("Initiating disconnection");
            
            _clientMain.releaseAll();
            _disconnectButton.setEnabled(false);
        }
        
    }
	
    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#connectionEstablishSuccessInd(three_star_craft.uap.UapGenerator, java.util.List)
     */
    public void connectionEstablishSuccessInd(UapGenerator gen,
            List<PlayableItem> playableItems)
    {
        _connectingDialog.setVisible(false);
        
        _disconnectButton.setEnabled(true);
        
        _clientMain.setAvailableMedia(playableItems);
        ((MediaTableModel)_mediaTable.getModel()).updateMedia(playableItems);
    }

    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#connectionEstablishFailInd(three_star_craft.uap.UapGenerator, UserApplicationPart.UAP.Cause)
     */
    public void connectionEstablishFailInd(UapGenerator gen, UAP.Cause cause)
    {
        _connectingDialog.setVisible(false);
        
        JOptionPane.showMessageDialog(
                GuiMain.this,
                "Server rejected connection with cause:"+cause.toString(),
                "Connection failed",
                JOptionPane.WARNING_MESSAGE,
                null);
        
        _connectButton.setEnabled(true);
    }

    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#connectionEstablishTimeout(three_star_craft.uap.UapGenerator)
     */
    public void connectionEstablishTimeout(UapGenerator gen)
    {
        _connectingDialog.setVisible(false);
        
        JOptionPane.showMessageDialog(
                GuiMain.this,
                "Connection establishment with Three Star Craft server timed out",
                "Connection failed",
                JOptionPane.WARNING_MESSAGE,
                null);
        
        _connectButton.setEnabled(true);
    }
    
    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#connectionReleaseInd(three_star_craft.uap.UapGenerator)
     */
    public void connectionReleaseInd(UapGenerator gen)
    {
        _connectButton.setEnabled(true);
        _disconnectButton.setEnabled(false);
    }
    
    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#mediaBearerSetupTimeout(three_star_craft.uap.UapGenerator)
     */
    public void mediaBearerSetupTimeout(UapGenerator uapGenerator)
    {
        _connectingDialog.setVisible(false);
        
        JOptionPane.showMessageDialog(
                GuiMain.this,
                "Media connection establishment failed",
                "Connection failed",
                JOptionPane.WARNING_MESSAGE,
                null);
    }

    /* (non-Javadoc)
     * @see three_star_craft.uap.UapConnectionListener#mediaBearerSetupConfirmInd(three_star_craft.uap.UapGenerator)
     */
    public void mediaBearerSetupConfirmInd(UapGenerator generator)
    {
        _connectingDialog.setVisible(false);
        
        // TODO show in GUI that playback is ready
    }
    
    
}
